import pandas as pd
from pandas.io.excel import ExcelFile
from pandas import DataFrame
import config
import file_processor
import copy

TABLES_LIST = {}
NAMES_LIST = []
USERS_STATE = {}

def parse_tables():
    global NAMES_LIST
    global TABLES_LIST
    xls = file_processor.get_excel()
    if xls is not None:
        NAMES_LIST = xls.sheet_names
        for n in NAMES_LIST:
            if n in config.SETTINGS['sheet_size'].keys():
                raw_table = xls.parse(n)
                TABLES_LIST[n] = read(raw_table, config.SETTINGS['sheet_size'][n])
    
       

def read(data, size: int):    
    first_header_row_pos = 0
    first_data_pos = 0
    last_data_pos = 0


    raw_header = None
    flat_header = None
    mapper = {}

    for i in range(data.shape[0]):     
        if str(data.iat[i, 0]).find('п/п') != -1:
            first_header_row_pos = i
        if data.iat[i, 0] == 1 and data.iat[i+1, 0] == 2:
            first_data_pos = i
            break
    
    for i in range(first_data_pos, data.shape[0]):
        if not pd.isnull(data.iat[i, 0]) and pd.isnull(data.iat[i+1, 0]):
            last_data_pos = i
            break
    
    remove_index = [i for i in range(first_header_row_pos)]
    remove_index.extend([j for j in range(last_data_pos+1, data.shape[0])])
    remove_index.append(first_data_pos -1)
    
    data.drop(index=remove_index, columns=data.columns[size:], inplace=True)
    raw_header = list(data.iloc[0])
    flat_header = list(data.iloc[0])

    
    for r in range(1, first_data_pos - first_header_row_pos - 1):
        for c in range(size):
            if not pd.isnull(data.iat[r, c]):
                if str(raw_header[c]).find(r'nan') == -1:
                    flat_header[c] = ",".join([str(raw_header[c]), str(data.iat[r, c])])
                else:
                    for i in reversed(range(c)):
                        if str(raw_header[i]).find(r'nan') == -1:
                            flat_header[c] = ",".join([str(raw_header[i]), str(data.iat[r, c])])
                            break
        raw_header = copy.copy(flat_header)
    
    for i in range(len(flat_header)):
        mapper[data.columns[i]] = flat_header[i]
    
    data = data.rename(columns=mapper)
    data = data.drop(index=[i for i in data.index if i < first_data_pos])
    return data

def get_line(table_name: str, pos: int):
    part_data = ''
    for i in range(TABLES_LIST[table_name].shape[1]):
        value = str(TABLES_LIST[table_name].iloc[pos,i])
        part_data += "{}:\t{}\n".format(TABLES_LIST[table_name].columns[i], value if value.find(r'nan') == -1 else "--")  
    return part_data


def get_dir_data(user_name: str, direction: str):
    if user_name in USERS_STATE.keys():
        current_table = USERS_STATE[user_name]['current_table']
        answer = get_data(user_name, current_table, direction)
        return answer
    else:
        return None
    

def get_data(user_name: str, table_name: str, direction: str):
    if len(NAMES_LIST) == 0:
        return None
    
    if user_name in USERS_STATE.keys():
        current_state = USERS_STATE[user_name]
        if table_name == current_state['current_table']:
            if direction == "next":
                return get_next(current_state)
            elif direction == "back":
                return get_previos(current_state)
        else:
            current_state['current_table'] = table_name
            current_state['current_line'] = -1
            return get_next(current_state)
    else:
        USERS_STATE[user_name] = {'current_table': table_name, 'current_line': -1}
        return get_next(USERS_STATE[user_name])
                

def get_next(user_state: dict):
    if user_state['current_line'] !=  TABLES_LIST[user_state['current_table']].shape[0] - 1:
        user_state['current_line'] += 1
        return get_line(user_state['current_table'], user_state['current_line'])
    else:
        return None
        
def get_previos(user_state: dict):
    if user_state['current_line'] !=  0:
        user_state['current_line'] -= 1
        return get_line(user_state['current_table'], user_state['current_line'])
    else:
        return None